package utils

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"

	"gitee.com/sansaniot/ssiot-core/logger"
)

func AesEncrypt(origData, key string) (string, error) {
	if len(key) == 0 {
		key = "aes1584407805313"
	}
	aesKey := []byte(key)
	val := []byte(origData)
	block, err := aes.NewCipher(aesKey)
	if err != nil {
		return "", err
	}
	blockSize := block.BlockSize()
	val = PKCS7Padding(val, blockSize)
	blockMode := cipher.NewCBCEncrypter(block, aesKey[:blockSize])
	crypted := make([]byte, len(val))
	blockMode.CryptBlocks(crypted, val)

	//byte数组转换字符串
	res := base64.StdEncoding.EncodeToString(crypted)
	return res, nil
}

func AesDecrypt(crypted, key string) (str string, err any) {
	defer func() {
		if err = recover(); err != nil {
			logger.Error(err)
		}
	}()
	if len(key) == 0 {
		key = "aes1584407805313"
	}
	aesKey := []byte(key)

	//字符串转换成byte数组
	val, _ := base64.StdEncoding.DecodeString(crypted)
	block, err := aes.NewCipher(aesKey)
	if err != nil {
		return "", err
	}
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, aesKey[:blockSize])
	origData := make([]byte, len(val))
	blockMode.CryptBlocks(origData, val)
	origData = PKCS7UnPadding(origData)

	//剔除空白字符
	res := []byte{}
	for i := range origData {
		val := origData[i]
		if val != 0 {
			res = append(res, val)
		}
	}
	return string(res), nil
}

func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}

func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}
